BROADWAY_EVENT_UNGRAB_NOTIFY = 'u',
BROADWAY_EVENT_CONFIGURE_NOTIFY = 'w',
BROADWAY_EVENT_DELETE_NOTIFY = 'W',
- BROADWAY_EVENT_SCREEN_SIZE_CHANGED = 'd'
+ BROADWAY_EVENT_SCREEN_SIZE_CHANGED = 'd',
+ BROADWAY_EVENT_FOCUS = 'f'
} BroadwayEventType;
typedef enum {
gint32 id;
} BroadwayInputDeleteNotify;
+typedef struct {
+ BroadwayInputBaseMsg base;
+ gint32 id;
+} BroadwayInputFocusMsg;
+
typedef union {
BroadwayInputBaseMsg base;
BroadwayInputPointerMsg pointer;
BroadwayInputConfigureNotify configure_notify;
BroadwayInputDeleteNotify delete_notify;
BroadwayInputScreenResizeNotify screen_resize_notify;
+ BroadwayInputFocusMsg focus;
} BroadwayInputMsg;
typedef enum {
BROADWAY_REQUEST_UPDATE,
BROADWAY_REQUEST_MOVE_RESIZE,
BROADWAY_REQUEST_GRAB_POINTER,
- BROADWAY_REQUEST_UNGRAB_POINTER
+ BROADWAY_REQUEST_UNGRAB_POINTER,
+ BROADWAY_REQUEST_FOCUS_WINDOW
} BroadwayRequestType;
typedef struct {
typedef struct {
BroadwayRequestBase base;
guint32 id;
-} BroadwayRequestDestroyWindow, BroadwayRequestShowWindow, BroadwayRequestHideWindow;
+} BroadwayRequestDestroyWindow, BroadwayRequestShowWindow, BroadwayRequestHideWindow, BroadwayRequestFocusWindow;
typedef struct {
BroadwayRequestBase base;
BroadwayRequestGrabPointer grab_pointer;
BroadwayRequestUngrabPointer ungrab_pointer;
BroadwayRequestTranslate translate;
+ BroadwayRequestFocusWindow focus_window;
} BroadwayRequest;
typedef enum {
GHashTable *id_ht;
GList *toplevels;
BroadwayWindow *root;
+ gint32 focused_window_id; /* -1 => none */
guint32 screen_width;
guint32 screen_height;
break;
case BROADWAY_EVENT_BUTTON_PRESS:
case BROADWAY_EVENT_BUTTON_RELEASE:
+ if (message->base.type == BROADWAY_EVENT_BUTTON_PRESS &&
+ server->focused_window_id != message->pointer.mouse_window_id)
+ broadway_server_focus_window (server, message->pointer.mouse_window_id);
+
server->last_x = message->pointer.root_x;
server->last_y = message->pointer.root_y;
server->last_state = message->pointer.state;
return sent;
}
+void
+broadway_server_focus_window (BroadwayServer *server,
+ gint new_focused_window)
+{
+ BroadwayInputMsg focus_msg;
+
+ if (server->focused_window_id == new_focused_window)
+ return;
+
+ /* Keep track of the new focused window */
+ server->focused_window_id = new_focused_window;
+
+ memset (&focus_msg, 0, sizeof (focus_msg));
+ focus_msg.base.type = BROADWAY_EVENT_FOCUS;
+ focus_msg.base.time = broadway_server_get_last_seen_time (server);
+ focus_msg.focus.id = new_focused_window;
+
+ broadway_events_got_input (&focus_msg, -1);
+}
+
guint32
broadway_server_grab_pointer (BroadwayServer *server,
gint client_id,
int y,
int width,
int height);
+void broadway_server_focus_window (BroadwayServer *server,
+ gint new_focused_window);
cairo_surface_t * broadway_server_open_surface (BroadwayServer *server,
guint32 id,
char *name,
send_reply (client, request, (BroadwayReply *)&reply_ungrab_pointer, sizeof (reply_ungrab_pointer),
BROADWAY_REPLY_UNGRAB_POINTER);
break;
+ case BROADWAY_REQUEST_FOCUS_WINDOW:
+ broadway_server_focus_window (server, request->focus_window.id);
+ break;
default:
g_warning ("Unknown request of type %d\n", request->base.type);
}
return sizeof (BroadwayInputDeleteNotify);
case BROADWAY_EVENT_SCREEN_SIZE_CHANGED:
return sizeof (BroadwayInputScreenResizeNotify);
+ case BROADWAY_EVENT_FOCUS:
+ return sizeof (BroadwayInputFocusMsg);
default:
g_assert_not_reached ();
}
return TRUE;
}
+void
+_gdk_broadway_server_window_focus (GdkBroadwayServer *server,
+ gint id)
+{
+ BroadwayRequestFocusWindow msg;
+
+ msg.id = id;
+ gdk_broadway_server_send_message (server, msg,
+ BROADWAY_REQUEST_FOCUS_WINDOW);
+}
+
void
_gdk_broadway_server_window_set_transient_for (GdkBroadwayServer *server,
gint id, gint parent)
gint id);
gboolean _gdk_broadway_server_window_hide (GdkBroadwayServer *server,
gint id);
+void _gdk_broadway_server_window_focus (GdkBroadwayServer *server,
+ gint id);
void _gdk_broadway_server_window_set_transient_for (GdkBroadwayServer *server,
gint id,
gint parent);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
-
- event = gdk_event_new (GDK_FOCUS_CHANGE);
- event->focus_change.window = g_object_ref (window);
- event->focus_change.in = TRUE;
- gdk_event_set_device (event, display->core_pointer);
-
- node = _gdk_event_queue_append (display, event);
- _gdk_windowing_got_event (display, node, event, message->base.serial);
}
break;
case BROADWAY_EVENT_LEAVE:
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
-
- event = gdk_event_new (GDK_FOCUS_CHANGE);
- event->focus_change.window = g_object_ref (window);
- event->focus_change.in = FALSE;
- gdk_event_set_device (event, display->core_pointer);
-
- node = _gdk_event_queue_append (display, event);
- _gdk_windowing_got_event (display, node, event, message->base.serial);
}
break;
case BROADWAY_EVENT_POINTER_MOVE:
_gdk_broadway_screen_size_changed (screen, &message->screen_resize_notify);
break;
+ case BROADWAY_EVENT_FOCUS:
+ window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->focus.id));
+ if (window)
+ {
+ event = gdk_event_new (GDK_FOCUS_CHANGE);
+ event->focus_change.window = g_object_ref (window);
+ event->focus_change.in = TRUE;
+ gdk_event_set_device (event, display->core_pointer);
+ node = _gdk_event_queue_append (display, event);
+ _gdk_windowing_got_event (display, node, event, message->base.serial);
+ }
+ break;
+
default:
g_printerr ("_gdk_broadway_events_got_input - Unknown input command %c\n", message->base.type);
break;
gdk_broadway_window_focus (GdkWindow *window,
guint32 timestamp)
{
+ GdkWindowImplBroadway *impl;
+ GdkBroadwayDisplay *broadway_display;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window) ||
+ !window->accept_focus)
+ return;
+
+ impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
+ broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window));
+ _gdk_broadway_server_window_focus (broadway_display->server,
+ impl->id);
}
static void